'use strict'

const path = require('path');

class Parser {

    constructor(options) {
        this._cfg = options;
        this._dest = '';
        this._reqURL = '';
        this._originalAddrList = new Array();
        this._protocol = '';
        this._host = '';
        this._prefixNum = 0;
        this._downloadAddrList = new Array();
        this._saveAddrList = new Array();
        this._replaceAddrList = new Array();
        this._cssBox = new Array();
    }

    currentURL() { return this._reqURL; }

    downloadAddrList() { return this._downloadAddrList; }

    saveAddrList() { return this._saveAddrList; }

    replaceAddrList() { return this._replaceAddrList; }

    cssBox() { return this._cssBox; }

    parse(dest, req, arrUrls) {
        this._dest = dest;
        this._reqURL = req.substr(req.length - 1) === '/' ? req : req + '/';
        this._originalAddrList = arrUrls;

        if (this._reqURL.substr(0, 7) != 'http://' && this._reqURL.substr(0, 8) != 'https://') {
            throw new Error();
        }

        this._protocol = this._reqURL.substr(0, 7) === 'http://' ? 'http://' : 'https://';
        const reg = new RegExp('https?://(.+)/');
        this._host = this._reqURL.match(reg)[1];

        const digFileName = (url) => {
            let arr = url.split('/');
            let fileName = arr.length > 1 ? arr[arr.length - 1] : url;

            let exclamationPos = fileName.indexOf('!');
            let questionPos = fileName.indexOf('?');
            if (exclamationPos > -1 || questionPos > -1) {
                if (exclamationPos > -1) fileName = fileName.substr(0, exclamationPos);
                if (questionPos > -1) fileName = fileName.substr(0, questionPos);
            }

            this._prefixNum += 1;

            return path.join(this._dest, this._prefixNum.toString(16) + '_' + fileName);
        }

        const parseUrl = (item) => {
            let parsed = digFileName(item);
            const firstOne = item.substr(0, 1);
            const firstTwo = item.substr(0, 2);

            if (parsed.endsWith(".php")) parsed += ".css";

            if (firstTwo === '//') {
                return {
                    downloadAddr: this._protocol + item.substr(2),
                    saveAddr: parsed,
                    replaceAddr: parsed
                };
            }

            if (firstTwo === './' || firstOne === '/') {
                const index = firstOne === '/' ? 1 : 2;

                return {
                    downloadAddr: this._protocol + this._host + '/' + item.substr(index, item.length - index),
                    saveAddr: parsed,
                    replaceAddr: parsed
                };
            }

            if (item.substr(0, 7) === 'http://' || item.substr(0, 8) === 'https://') {
                return {
                    downloadAddr: item,
                    saveAddr: parsed,
                    replaceAddr: parsed
                };
            }

            return {
                downloadAddr: this._protocol + this._host + '/' + item,
                saveAddr: parsed,
                replaceAddr: parsed
            };
        }

        const decodeURL = (url) => {
            return url.replace(/&amp;/g, '&');
        }

        this._originalAddrList.forEach((addr) => {
            let surround = '';
            let matched = false;

            this._cfg.surround.forEach((sur) => {
                if (!matched && addr.substr(0, sur.length) === sur) {
                    matched = true;
                    surround = sur;
                    addr = addr.substr(surround.length, addr.length - 2 * surround.length);
                }
            });

            const ret = parseUrl(addr);
            this._downloadAddrList.push(decodeURL(ret.downloadAddr));
            this._saveAddrList.push(ret.saveAddr);
            surround != '' ? this._replaceAddrList.push(surround + ret.replaceAddr + surround) : this._replaceAddrList.push(ret.replaceAddr);

            if (ret.saveAddr.substr(ret.saveAddr.length - 4) === '.css') {
                let pos = ret.downloadAddr.lastIndexOf('/');

                this._cssBox.push({
                    css: ret.saveAddr,
                    dir: ret.downloadAddr.substr(0, pos + 1)
                });
            }
        });
    }
}

module.exports = Parser;

/*
module.exports = {
    reset: reset,
    config: config,
    mockId: mockId,
    parse: parse,
    currentURL: () => { return this._reqURL; },
    this._downloadAddrList: () => { return this._downloadAddrList; },
    this._saveAddrList: () => { return this._saveAddrList; },
    this._replaceAddrList: () => { return this._replaceAddrList; },
    this._cssBox: () => { return this._cssBox; }
};
*/